/*
 * Copyright (C) Francisco Morero Peyrona. All rights reserved.
 *
 * This software is published under the terms of Open Source
 * License version 1.1, a copy of which has been included with this
 * distribution in the License.txt file.
 */

package jdbcmanager.dbtools.agentwise;

import java.sql.*;

import jdbcmanager.dbtools.datatypes.*;

/**
 * This interface defines all functionality that an SQL Agent has to have.
 * <p>
 * An SQL Agent is a piece of code with 2 goals:
 * <ul>
 *   <li> Knows how to convert a definition (table, relation, ...) into the SQL Command for the target DBMS
 *   <li> Provides extra needed functionality (that should be in DataBaseMetaData, but that does not exists)
 * </ul>
 * <p>
 * JDBC Manager relies on SQL Agents to create and drop tables, alter tables structure, create and drop
 * relations, etc.
 * <p>
 * The problem is that every DBMS has its own SQL dialect and therefore, an AgentSQL is needed to "talk"
 * with its DBMS. In this way there should be one AgentSQL for every DBMS.
 * <p>
 * AgentSQLs should inherit from the default one, named 'AgentSQLDefault'
 * <p>
 * Implementators of this class are garanteed to receive congruent information and "clean". For example,
 * if a table has to be created, there will be at least one column, the table and column(s) names will
 * be normalized, the user will be asked to confirm befored deleting a table... etc. And all this is
 * don before invoking methods defined in this interface, therefore, this interface implentators just 
 * have to do their job, without worring about all these mentioned issues. 
 *
 * @author Francisco Morero Peyrona
 */
public interface AgentSQL
{   
   //-------------------------------------------------------------------------//
   // CATALOG RELATED METHODS   
   //-------------------------------------------------------------------------//
   
   /**
    * Creates a Catalog (DataBase).
    *
    * @param sName Name of the catalog
    * @return  <code>true</code> if succeeded otherwise <code>false</code>.
    */
   public boolean createCatalog( Connection conn, String sName );
 
   /**
    * Deletes (drop) a Catalog (DataBase).
    *
    * @param sName Name of the catalog
    * @return  <code>true</code> if succeeded otherwise <code>false</code>.
    */  
   public boolean dropCatalog( Connection conn, String sName );
   
   /**
    * Return <code>true</code> if the DBMS allows to rename an existing catalog, otherwise <code>false</code>.
    * <p>
    * Should be redefined by subclases of <code>AgentSQLDefault</code>.
    * 
    * @return In <code>AgentSQLDefault</code> implementation returns <code>false</code> 
    */
   public boolean allowsCatalogCreation();
   
   /**
    * Return <code>true</code> if the DBMS allows to create new data bases (catalogs), otherwise <code>false</code>.
    * <p>
    * Should be redefined by subclases of <code>AgentSQLDefault</code>.
    * <p>
    * It is assumed that if DBMS allows creation it will also allow destruction (drop). 
    * 
    * @return In <code>AgentSQLDefault</code> implementation returns <code>false</code>
    */
   public boolean allowsCatalogRename();
      
   /**
    * Renames a catalog.
    * <p>
    * Should be redefined by subclases of <code>AgentSQLDefault</code>.
    * 
    * @param conn
    * @param OldName
    * @param sNewName
    * @return Always <code>false</code> in <code>AgentSQLDefault</code> implementation.
    */
   public boolean renameCatalog( Connection conn, String OldName, String sNewName );
   
   //-------------------------------------------------------------------------//
   // TABLE RELATED METHODS   
   //-------------------------------------------------------------------------//
     
   /**
    * Creates a table, its indices and relations.
    * 
    * @param conn
    * @param def
    * @return 
    */
   public boolean createTable( Connection conn, TableDefinition def );
   
   /**
    * 
    * @param conn
    * @param defOld
    * @param defNew
    * @return
    */
   public boolean alterTable( Connection conn, TableDefinition defOld, TableDefinition defNew );
   
   /**
    * Rename a table.
    * 
    * @param conn
    * @param ded
    * @param sNewName
    * @return
    */
   public boolean renameTable( Connection conn, TableDefinition table, String sNewName );
   
   /**
    * Simply drops a table.
    * 
    * @param conn
    * @param ded
    * @return
    */
   public boolean dropTable( Connection conn, DbEntityDescriptor ded );
   
   //-------------------------------------------------------------------------//
   // OTHER METHODS
   //-------------------------------------------------------------------------//
   
   /**
    * Returns <code>true</code> if the passed table column data type has a variable length,
    * like VARCHAR for example, otherwise returnes <code>false</code>.
    * <p>
    * I know that this method should be in <code>TableColumnTypeDefinition</code> class, but it is here just
    * to make easier for other developers to create their own SQL Agents: in this way they can just inherit
    * from this class and do not need to inherit also from <code>TableColumnTypeDefinition</code>.
    * 
    * @param tctd Type to check
    * @return <code>true</code> if passed parameter is a variable length type.
    */
   public boolean isVariableLengthType( TableColumnTypeDefinition tctd );
   
   /**
    * Checks if passed table colunm is valid.
    * 
    * @param column Column to be validated.
    * @return <code>true</code> if passed column is valid.
    */
   public boolean isValidColumn( TableColumnDefinition column );
   
   /**
    * Checks if passed relation is valid.
    * 
    * @param relation Relation to be validated.
    * @return <code>true</code> if passed relation is valid.
    */
   public boolean isValidRelation( RelationDefinition relation ); 
   
   /**
    * Checks if passed index is valid.
    * 
    * @param index Index to be validated.
    * @return <code>true</code> if passed index is valid.
    */
   public boolean isValidIndex( IndexDefinition index );
   
   /**
    * Normalizes passed name to be accepted by the DBMS. 
    * 
    * @param  sName Name to normalize
    * @param  nEntityType Type of DB entity (see <code>DbEntityTypes</code> class)
    * @return The name after been normalized.
    */
   public String normalizeDbEntityName( String sName, int nEntityType );
   
   /**
    * Return the SQL command needed to create the table where diagrams are stored.
    * <p>
    * The defult implementation has minimum usability, therefore it is important to 
    * redefine this method for every DBMS.
    * 
    * @return The SQL command needed to create table where diagrams are stored
    */
   public String getCreateDiagramTableSQLCommand();
}